﻿
//依赖项：
//mfcvcr100.dll;kernel32.dll



#include "../common/serialport.h"
#include "stdio.h"
//作为已知类型
struct stageInterface
{
	bool (*openCom)(int portnum);
	void (*closeCom)();

	void (*gr)(long x,long y);
	void (*g2)(long x,long y);
	void (*g3)(long x,long y,long z);

	//z
	void (*zup)(long len);
	void (*zdown)(long len);
	void (*v)(int z);//um/s;
	//
	void (*sp)(int speed);
	void (*spz)(int speedz);

	void (*stop)();
	//
	void (*getcurpos)(long& x,long&y,long&z);//微米
	void (*px)(long x);//um
	void (*py)(long x);
	void (*pz)(long x);
	//
	void (*vs)(int x,int y);
	void (*vz)(int z);
};

static serialPort com;
static HANDLE evtstack[20];
static int stacksize=0;

//dll入口
BOOL APIENTRY DllMain( HANDLE hModule,
	DWORD  ul_reason_for_call,
	LPVOID lpReserved
	)
{
	switch( ul_reason_for_call )
	{
	case DLL_PROCESS_ATTACH:break;
	case DLL_THREAD_ATTACH:break;
	case DLL_THREAD_DETACH:break;
	case DLL_PROCESS_DETACH:
		com.CloseCom();
	}
	return TRUE;
}


//私有
bool send(const char* cmd)
{
	char buffer[200];
	strcpy(buffer,cmd);
	int len=strlen(cmd);
	buffer[len]='\r';
	buffer[len+1]=0;
	if(!com.WriteCom(buffer))
	{
		MessageBoxA(0,"发送失败","锁相串口",0);
		return false;
	}
	return true;
}
bool read(char* dat)
{
	if(!com.ReadCom(dat))
	{
		MessageBoxW(0,L"读取失败",L"锁相串口",0);
		return false;
	}
	return true;
}

void waitcom()
{

	//ClearCommError(com.hComm,NULL,NULL);
	while(true)
	{
		OVERLAPPED ov;
		memset(&ov,0,sizeof(OVERLAPPED));
		ov.hEvent=CreateEventA(NULL,TRUE,FALSE,NULL);
		DWORD dwEventMask;
		if (WaitCommEvent(com.hComm, &dwEventMask, &ov)) 
		{
			MessageBoxW(0,L"立即有数据？",L"锁相串口",0);
			if (dwEventMask & EV_RXCHAR) 
			{
				MessageBoxW(0,L"确实如此",L"锁相串口",0);
			}
		}
		else
		{
			DWORD dwRet = GetLastError();
			if( ERROR_IO_PENDING == dwRet)
			{
				WaitForSingleObject(ov.hEvent,INFINITE);
				DWORD dwerror;
				COMSTAT stat;
				ClearCommError(com.hComm,&dwerror, &stat);
				if(stat.cbInQue==0)
					continue;
				else
					break;
			}
///
			/*else 
			{
				char ssss[200];
				sprintf(ssss,"等待错误 code=%d",dwRet);
				MessageBoxA(0,ssss,"锁相串口",0);
			}*/
		}
		CloseHandle(ov.hEvent);//ClearCommError(com.hComm,NULL,NULL);

	}

}
//附带清除返回数据
void waitcomNdel()
{
	waitcom();
	//PurgeComm(com.hComm,PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_RXABORT | PURGE_TXABORT);
	//PurgeComm(com.hComm,PURGE_RXCLEAR|PURGE_TXCLEAR);//删除R
	char ans[200];
	read(ans);
	//MessageBoxA(0,ans,"锁相串口",0);
}

DWORD _stdcall listener(LPVOID para)
{
	while(true)
	{
		WaitForMultipleObjects(stacksize,evtstack,TRUE,INFINITE);
		//等待到一个信号就减少计数
		stacksize=0;

	}
}

//接口
void initStageState()
{
	send("COMP 1");//兼容模式，移动后返回R
	waitcomNdel();
	//开始监听线程
	//::CreateThread(NULL,NULL,listener,NULL,NULL,0);

}

bool openCom(int portnum)
{
	if( com.OpenCom(portnum))
	{
		initStageState();
		return true;
	}
	return false;
}

void closeCom()
{
	com.CloseCom();
}

static const int base=100;
void gr(long x,long y)//微米
{
	char cmd[100];
	sprintf(cmd,"GR %ld,%ld",base*x,base*y);
	send(cmd);
	waitcomNdel();
}
void g(long x,long y)
{
	char cmd[100];
	sprintf(cmd,"G %ld,%ld",base*x,base*y);
	send(cmd);
	waitcomNdel();
}
void g(long x,long y,long z)
{
	char cmd[100];
	sprintf(cmd,"GR %ld,%ld,%ld",base*x,base*y,5*base*z);
	send(cmd);
	waitcomNdel();
}

//z
void zup(long len)//微米
{
	char cmd[100];
	sprintf(cmd,"D %ld",5*base*len);
	send(cmd);
	waitcomNdel();
}
void zdown(long len)
{
	char cmd[100];
	sprintf(cmd,"U %ld",5*base*len);
	send(cmd);
	waitcomNdel();
}
void v(int z)//um/s
{
	char cmd[100];
	sprintf(cmd,"V %ld",base*z);
	send(cmd);
	waitcomNdel();
}
//
void sp(int speed)
{
	char cmd[100];
	sprintf(cmd,"SMS %d",speed);
	send(cmd);
	waitcomNdel();
}
void spz(int speedz)
{
	char cmd[100];
	sprintf(cmd,"SMZ %d",speedz);
	send(cmd);
	waitcomNdel();
}

void stop()
{
	send("K");
	PurgeComm(com.hComm, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
}
//
void getcurpos(long& x,long&y,long&z)//微米
{
	send("P");
	waitcom();
	char dat[100]="",tmp[30]="";
	int index=0;
	read(dat);
	int len=strlen(dat);
	for(int i=0;i<len;i++)
	{
		if(dat[i]==';')
		{
			++index;
			if(index>2)
				return;
			else if(index==1)
			{
				x=atoi(tmp);
				memset(tmp,0,strlen(tmp));
			}
			else if(index==2)
			{
				y=atoi(tmp);
				memset(tmp,0,strlen(tmp));
			}
		}
		else
		{
			int len=strlen(tmp);
			tmp[len]=dat[i];
			tmp[len+1]='\0';
		}
	}
	z=atoi(tmp);
}

void px(long x)//微米
{
	char cmd[100];
	sprintf(cmd,"PX %ld",base*x);
	send(cmd);
	waitcomNdel();
}
void py(long x)//微米
{
	char cmd[100];
	sprintf(cmd,"PY %ld",base*x);
	send(cmd);
	waitcomNdel();
}
void pz(long x)//微米
{
	char cmd[100];
	sprintf(cmd,"PZ %ld",base*5*x);
	send(cmd);
	waitcomNdel();
}

//
void vs(int x,int y)
{
	char cmd[100];
	sprintf(cmd,"VS %ld,%ld",x,y);
	send(cmd);
	waitcomNdel();

}
void vz(int z)
{
	char cmd[100];
	sprintf(cmd,"VZ %ld",5*z);
	send(cmd);
	waitcomNdel();

}



extern "C" __declspec(dllexport) void setupStageEngine(stageInterface& dest)
{
	dest.openCom=openCom;
	dest.closeCom=closeCom;

	dest.gr=gr;
	dest.g2=g;
	dest.g3=g;

	//z
	dest.zup=zup;
	dest.zdown= zdown;
	dest.v=v;
	//
	dest.sp=sp;
	dest.spz=spz;

	dest.stop=stop;
	//
	dest.getcurpos=getcurpos;//
	dest.px=px;//微米
	dest.py=py;
	dest.pz=pz;
	//
	dest.vs=vs;
	dest.vz=vz;
}


